// Fill out your copyright notice in the Description page of Project Settings.

#include "ProceduralTerrain.h"
#include "Runtime/Engine/Classes/Kismet/KismetMathLibrary.h"
#include "Runtime/Core/Public/Math/NoiseSimplified.h"

UProceduralTerrain::UProceduralTerrain()
{
    // 设置默认值
    NoiseSeed = 12345;
    NoiseScale = 100.0f;
    Octaves = 4;
    Persistence = 0.5f;
    Lacunarity = 2.0f;
    MaxHeight = 100.0f;
    MinHeight = -50.0f;
    
    // 启用组件更新
    PrimaryComponentTick.bCanEverTick = true;
    
    // 记录组件初始化
    FWinstonLogger::Get().Debug(TEXT("ProceduralTerrain"), TEXT("Component initialized with default settings"));
}

void UProceduralTerrain::BeginPlay()
{
    Super::BeginPlay();
    
    // 初始化地形（使用默认参数）
    GenerateProceduralTerrain(NoiseSeed, NoiseScale, Octaves, Persistence, Lacunarity);
    
    // 记录地形组件开始运行
    FWinstonLogger::Get().Info(TEXT("ProceduralTerrain"), TEXT("Terrain component started"));
}

void UProceduralTerrain::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
    Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
    
    // 地形组件通常不需要每帧更新，除非有动态变化
    // 可以在这里添加地形动态变化逻辑，如地形变形等
}

void UProceduralTerrain::GenerateProceduralTerrain(int32 Seed, float InNoiseScale, int32 InOctaves, float InPersistence, float InLacunarity)
{
    // 更新参数
    NoiseSeed = Seed;
    NoiseScale = InNoiseScale;
    Octaves = InOctaves;
    Persistence = InPersistence;
    Lacunarity = InLacunarity;
    
    // 记录地形生成开始
    FWinstonLogger::Get().Info(
        TEXT("ProceduralTerrain"), 
        TEXT("Starting terrain generation - Seed: %d, Scale: %f, Octaves: %d, Persistence: %f, Lacunarity: %f"),
        Seed, InNoiseScale, InOctaves, InPersistence, InLacunarity
    );
    
    // 这里是地形生成的核心逻辑
    // 在实际项目中，这里应该与Landscape组件交互，或者生成地形网格
    // 由于这是基础实现，我们只是记录日志并设置参数
    
    // 记录地形生成完成
    FWinstonLogger::Get().Info(TEXT("ProceduralTerrain"), TEXT("Terrain generation parameters set"));
    
    // 在实际项目中，这里应该调用Landscape的API来设置高度图
}

float UProceduralTerrain::GetHeightAt(float X, float Y)
{
    // 生成分形噪声值
    float NoiseValue = GenerateFractalNoise(X, Y);
    
    // 将噪声值映射到指定的高度范围
    float Height = UKismetMathLibrary::Lerp(MinHeight, MaxHeight, (NoiseValue + 1.0f) * 0.5f);
    
    return Height;
}

float UProceduralTerrain::GenerateNoise(float X, float Y)
{
    // 使用UE的噪声函数
    FVector2D Position(X, Y);
    return FMath::PerlinNoise2D(Position * NoiseScale + NoiseSeed);
}

float UProceduralTerrain::GenerateFractalNoise(float X, float Y)
{
    float Total = 0.0f;
    float Amplitude = 1.0f;
    float Frequency = 1.0f;
    float MaxValue = 0.0f; // 用于归一化
    
    // 生成多层噪声
    for (int32 i = 0; i < Octaves; i++)
    {
        float Noise = GenerateNoise(X * Frequency, Y * Frequency);
        Total += Noise * Amplitude;
        
        MaxValue += Amplitude;
        Amplitude *= Persistence;
        Frequency *= Lacunarity;
    }
    
    // 归一化结果
    return Total / MaxValue;
}

float UProceduralTerrain::Lerp(float A, float B, float T)
{
    return A + (B - A) * T;
}

float UProceduralTerrain::Smoothstep(float A, float B, float T)
{
    T = FMath::Clamp(T, 0.0f, 1.0f);
    T = T * T * (3.0f - 2.0f * T);
    return Lerp(A, B, T);
}